package cc.eddic.pratice.programmingparadigms.nginxlog.impl;

import cc.eddic.pratice.programmingparadigms.emp02list.impl.ResultListGcsImpl;
import cc.eddic.pratice.programmingparadigms.nginxlog.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

public class LogReportLxImpl implements LogReport {
    private static final Logger log = LoggerFactory.getLogger(ResultListGcsImpl.class);

    @Override
    public PageViewsAndUniqueVisitors pageViewsAndUniqueVisitors(List<NginxLogItem> items) {

//        uv统计
        long pageViews = items.size();
//        pv统计
        long uniqueVisitors = items.stream().map(i -> i.getIp() + i.getUserAgent()).distinct().count();
        if (log.isDebugEnabled()) log.debug("pv: {},uv{}", pageViews, uniqueVisitors);
        return new PageViewsAndUniqueVisitors(pageViews, uniqueVisitors);
    }

    @Override
    public Map<Integer, PageViewsAndUniqueVisitors> pageViewsAndUniqueVisitorsByHour(List<NginxLogItem> items) {
        return items.stream().collect(Collectors.groupingBy(this::getHour))
                .entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, hc -> pageViewsAndUniqueVisitors(hc.getValue())));
    }

    private int getHour(NginxLogItem n) {
        String[] times = n.getTime().split("/");
        for (int i = 0; i < times.length; i++) {
            if (!Character.isDigit(times[i].charAt(0))) {
                String[] hours = times[i + 1].split(":");
                for (int j = 1; j < hours.length; j = j + 4) {
                    if (log.isDebugEnabled()) log.debug("path: {}", hours[j]);
                    return Integer.parseInt(hours[j]);
                }
            }
        }
        return -1;
    }

    private PageViewsAndUniqueVisitors pageViewsAndUniqueVisitors1(List<LogItem> items) {
        //        uv统计
        long pageViews = items.size();
//        pv统计
        long uniqueVisitors = items.stream().map(i -> i.getIp() + i.getUserAgent()).distinct().count();
        if (log.isDebugEnabled()) log.debug("pv: {},uv{}", pageViews, uniqueVisitors);
        return new PageViewsAndUniqueVisitors(pageViews, uniqueVisitors);
    }

    @Override
    public List<PathModel> pageViewsAndUniqueVisitorsByPath(List<LogItem> items) {
        return items.stream().collect(Collectors.groupingBy(LogItem::getPath))
                .entrySet().stream()
                .map(hc -> new PathModel(hc.getKey(), pageViewsAndUniqueVisitors1(hc.getValue()).getPageViews(),
                        pageViewsAndUniqueVisitors1(hc.getValue()).getUniqueVisitors())).collect(Collectors.toList())
                .stream().sorted(Comparator.comparing(PathModel::getPv).reversed()).collect(Collectors.toList());
    }
}
